package com.jrzh.config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;

import com.jrzh.security.CustomUserDetailsService;
import com.jrzh.security.LoginSuccessHandler;

/**
 *  服务端安全策略配置
 * @author Xanthin
 *
 */
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
	
	@Autowired @Qualifier("dataSource")
    private DataSource dataSource;
	
	@Autowired
	private CustomUserDetailsService customUserDetailsService;
	
		//引用customUserDetailsService配置用户认证
		@Override
		protected void configure(AuthenticationManagerBuilder auth)throws Exception {
			auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
			auth.eraseCredentials(false);
		}
		
		//Spring Security官方推荐的加密算法，比MD5算法安全性更高
		private BCryptPasswordEncoder passwordEncoder() {
			return new BCryptPasswordEncoder();
		}
		
		@Override
	    protected void configure(HttpSecurity http) throws Exception {
	        http.formLogin().loginPage("/login").permitAll().successHandler(loginSuccessHandler())
	                .and().authorizeRequests()
	                .antMatchers("/images/**", "/checkcode", "/scripts/**", "/styles/**","/druid/**").permitAll()
	                .anyRequest().authenticated()
	                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER)
	                .and().exceptionHandling().accessDeniedPage("/deny")
	                .and().rememberMe().tokenValiditySeconds(86400).tokenRepository(tokenRepository());
	    }
		
		//自定义的登录成功处理器
		@Bean
		public LoginSuccessHandler loginSuccessHandler() {
			return new LoginSuccessHandler();
		}
		
		//记住登录状态
		@Bean
		public JdbcTokenRepositoryImpl tokenRepository(){
			JdbcTokenRepositoryImpl jtr =  new JdbcTokenRepositoryImpl();
			jtr.setDataSource(dataSource);
			return jtr;
		}

}
